/* 
 * File:   Figura.cpp
 * Author: mm021791
 * 
 * Created on 26 de septiembre de 2012, 09:16
 */
#include <string>

#include "Figura.h"
#include "BMPHeader.h"

using namespace TP::Grafica::Renderizado;
using namespace TP::Grafica::Componentes;
    
Figura::Figura(){}

Figura::Figura(const char pTipo, Posicion* pPosicion) {
    
    this->tipo = pTipo;
    this->posicion = pPosicion;
    this->altura = 0;
    this->ancho = 0;
    this->posicionGrafica = NULL;
    this->pixels = NULL;
    
}

Figura::~Figura() {
    
    if (this->pixels)
    {
        // Elimino los pixels
        for (unsigned long int i = 0; i < this->altura; i++)
        {
            for (unsigned long int j = 0; j < this->ancho; j++)
                    delete this->pixels[i][j];
            delete [] this->pixels[i];
        }
        delete [] this->pixels;
    }
    
    // Elimino la posicion.
    if (this->posicion)
        delete this->posicion;
    
    // Elimino la posicion gráfica.
    if (this->posicionGrafica)
        delete this->posicionGrafica;
}

const char& Figura::getTipo () const{
    return this->tipo;
}

Posicion& Figura::getPosicion () const {
    return *this->posicion;
}

Posicion& Figura::getPosicionGrafica() const {
    return *this->posicionGrafica;
}

Pixel& Figura::getPixel (long int pFila, long int pColumna) const {
    return *(this->pixels[pFila][pColumna]);
}

const Pixel& Figura::setPixel (long int pFila, long int pColumna, Pixel* pPixel) throw(FiguraException&){
    
    if (pPixel && pFila >= 0 && pColumna >= 0)
    {
        this->pixels[pFila][pColumna] = pPixel;

        return *(this->pixels[pFila][pColumna]);
    }
    else
        throw FiguraException ("No se puede agregar el pixel.");
}

long int Figura::width() {
    return this->ancho;
}

long int Figura::height() {
    return this->altura;
}

namespace TP{ namespace Grafica { namespace Componentes { 
    
    ifstream& operator>> (ifstream& stream, Figura& figura) throw (FiguraException&) {
        
        if (stream.is_open())
        {
            // Leo el header del archivo BMP que compone el template de la figura.
            BMPHeader header;
            stream >> header;
                
            // Configuro las propiedades de la figura.
            figura.altura = header.GetBmpHeight();
            figura.ancho = header.GetBmpWidth();
            
            // Levanto en memoria la figura.
            figura.pixels = new Pixel** [figura.altura];
            for (unsigned long int cur = 0; cur < figura.altura; cur++)
                figura.pixels[cur] = new Pixel* [figura.ancho];
            
            stream.seekg(header.GetOffBits(), ifstream::ios_base::beg);
                    
            for (int i = header.GetBmpHeight() - 1; i >= 0 ; i--)
            {
                for(int j = 0; j < header.GetBmpWidth(); j++)
                {
                    Pixel* pixel = new Pixel();
                    stream >> *pixel;
                    
                    if (pixel->getR() == 255 && pixel->getG() == 0 && pixel->getB() == 0)
                    {
                        // Es el pixel ancla (Rojo).  Suplanto el pixel por el pixel negro.
                        delete pixel;
                        pixel = new Pixel(0,0,0);
                        
                        // Se calcula y configura la posición de la figura.  
                        Posicion ancla_figura (i, j, ROTACION_NULA);
                        figura.posicionGrafica = new Posicion (*figura.posicion - ancla_figura);
                    }
                    
                    figura.setPixel(i, j, pixel);
                }
                stream.seekg(figura.ancho % 4, ifstream::ios_base::cur);
            }
        }
        else
            throw FiguraException ("No se puede leer el template de la figura del stream de entrada.");        
        
        return stream;
    }

    
}}}
